package ui;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.RenderingHints.Key;
import java.awt.color.ColorSpace;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.ColorConvertOp;
import java.awt.image.RescaleOp;
import java.util.HashMap;


import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import javax.swing.Timer;

import layout.TableLayout;

public class LoadPanel extends JPanel {
	private static final long serialVersionUID = 1L;
	private SwingWorker<Boolean, Void> ie;
	private Timer refreshTimer;
	private JProgressBar wartenLabel;
	private BufferedImage bgimage;
	private double[][] tbSize = new double[][] { { TableLayout.FILL, 0.7, TableLayout.FILL },
			{ TableLayout.FILL, 0.2, TableLayout.FILL } };
	private RenderingHints hints;
	

	public LoadPanel(SwingWorker<Boolean, Void> ie, int width, int height,
			BufferedImage bgimage) {
		this.ie = ie;
		HashMap<Key, Object> map = new HashMap<Key, Object>();
		map.put(RenderingHints.KEY_INTERPOLATION,
				RenderingHints.VALUE_INTERPOLATION_BILINEAR);

		map.put(RenderingHints.KEY_RENDERING,
				RenderingHints.VALUE_RENDER_QUALITY);

		map.put(RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);
		hints = new RenderingHints(map);
		
		this.bgimage = bgimage != null ? addWhiteLayerTo(bgimage) : null;
		addAutoRefresh();
		this.setLayout(new TableLayout(tbSize));
		this.setOpaque(false);		
		this.wartenLabel = new JProgressBar();
		this.wartenLabel.setStringPainted(true);
		this.wartenLabel.setForeground(Color.GRAY);
		this.add(this.wartenLabel,"1,1");
		this.setPreferredSize(new Dimension(width, height));
		revalidate();
		repaint();
	}

	private BufferedImage addWhiteLayerTo(BufferedImage source) {
		BufferedImage aimg = new BufferedImage(source.getWidth(),
				source.getHeight(), BufferedImage.TRANSLUCENT);
		Graphics2D g = aimg.createGraphics();
		g.addRenderingHints(hints);
		g.drawImage(source, null, 0, 0);

		AlphaComposite alpha = AlphaComposite.getInstance(
				AlphaComposite.SRC_ATOP, 0.8f);
		g.setComposite(alpha);
		g.setColor(Color.white);		
		g.drawImage(getWhiteLayer(source), null, 0, 0);
		g.dispose();
		return aimg;		
	}

	private BufferedImage getWhiteLayer(BufferedImage source) {
		BufferedImage aimg = new BufferedImage(source.getWidth(),
				source.getHeight(), BufferedImage.TRANSLUCENT);
		Graphics2D g = aimg.createGraphics();
		g.addRenderingHints(hints);
		g.setColor(Color.GRAY);
		g.fillRect(0, 0, source.getWidth(), source.getHeight());		
		g.dispose();
		return aimg;
	}
	
	
	public void paintComponent(Graphics g) {
		if (bgimage != null)
			g.drawImage(bgimage, 0, 0, null);
	}

	public static BufferedImage convertToGrayscale(BufferedImage source) {
		BufferedImageOp op = new ColorConvertOp(
				ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
		return op.filter(source, null);
		
	}
	
	


	public BufferedImage adjustBrightness(BufferedImage source, float brightness) {
//		BufferedImage brighterImage = new BufferedImage(source.getWidth(),
//				source.getHeight(), source.getType());
//		float[] scaleFactors = { brightness, brightness, brightness };
//		RescaleOp rescaleOp = new RescaleOp(scaleFactors, new float[3], null);
//		((Graphics2D) brighterImage.getGraphics()).drawImage(source, rescaleOp,	0, 0);
		
		RescaleOp rescaleOp = new RescaleOp(brightness, 15, null);
		BufferedImage brighterImage = rescaleOp.filter(source, source);  // Source and destination are the same.

		return brighterImage;
	}

	private void addAutoRefresh() {
		this.refreshTimer = new Timer(50, new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				refresh();
			}
		});
		refreshTimer.start();
	}

	protected void refresh() {
		if (ie != null) {
			this.wartenLabel.setValue(ie.getProgress()==100?100:ie.getProgress());
			if(this.wartenLabel.getValue()==100) this.ie=null;
		}
	}

}
